export default class Vector2 {
    x: number;
    y: number;
    constructor(x = 0, y = 0) {
        this.x = x;
        this.y = y;
    }
    set(x: Vector2['x'], y: Vector2['y']) {
        this.x = x;
        this.y = y
    }
    setX(x: Vector2['x']) {
        this.x = x;
        return this
    }
    setY(y: Vector2['y']) {
        this.y = y
        return this
    }
    // 拷贝
    copy(v2: Vector2) {
        this.x = v2.x
        this.y = v2.y
    }
    // 克隆
    clone() {
        return new Vector2(this.x, this.y)
    }
    // 减法
    sub(v: Vector2): this {
        this.x -= v.x;
        this.y -= v.y;
        return this
    }
    // 加法
    add(v: Vector2): this {
        this.x += v.x;
        this.y += v.y;

        return this;
    }
    subVectors(a: Vector2, b: Vector2) {
        this.x = a.x - b.x;
        this.y = a.y - b.y;

        return this;
    }
    addVectors(a: Vector2, b: Vector2) {
        this.x = a.x + b.x;
        this.y = a.y + b.y;

        return this;
    }
    addScalar(s: number) {
        this.x += s;
        this.y += s;

        return this;

    }
    lengthSq() {

        return this.x * this.x + this.y * this.y;

    }
    dot(v: Vector2) {
        return this.x * v.x + this.y * v.y;

    }

    angleTo(v: Vector2) {

        const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());

        if (denominator === 0) return Math.PI / 2;

        const theta = this.dot(v) / denominator;

        // clamp, to handle numerical problems

        return Math.acos(theta);

    }
    angle() {

        // computes the angle in radians with respect to the positive x-axis

        const angle = Math.atan2(- this.y, - this.x) + Math.PI;

        return angle;

    }
    distanceTo(v: Vector2) {

        return Math.sqrt(this.distanceToSquared(v));

    }
    length() {

        return Math.sqrt(this.x * this.x + this.y * this.y);

    }
    normalize() {

        return this.divideScalar(this.length() || 1);

    }
    divideScalar(scalar: number) {

        return this.multiplyScalar(1 / scalar);

    }
    multiplyScalar(scalar: number) {

        this.x *= scalar;
        this.y *= scalar;

        return this;

    }
    distanceToSquared(v: Vector2) {

        const dx = this.x - v.x, dy = this.y - v.y;
        return dx * dx + dy * dy;

    }

}